package com.smartboard.network.server;

import com.smartboard.network.game.AbstractGame;
import com.smartboard.network.game.IPlayGame;
import com.smartboard.network.game.IRoom;
import com.smartboard.network.game.IUser;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

/**
 * Created by cheas on 2018/8/13.
 */

public class Room implements IRoom, Serializable {
    private static final long serialVersionUID = 1L;

    private static final String TAG = "Room";

    private int mId;
    private String mName;            // name of room
    private IUser mOwner;
    private List<IPlayGame> mGames;   // games in this room
    private List<IUser> mUsers;       // users in this room
    private String mPassword;

    private Room() {

    }

    public Room(String name, IUser owner, String password) {
        mName = name;
        mId = IdsPool.createId(IdsPool.ID_TYPE_ROOM, owner.getChessType());
        mOwner = owner;
        mPassword = password;
        mGames = new ArrayList<>();
        mUsers = new ArrayList<>();
        IdsPool.addObject(mId, this);
    }

    @Override
    public int getId() {
        return mId;
    }

    @Override
    public String getName() {
        return mName;
    }

    public void setName(String name) {
        mName = name;
    }

    @Override
    public IUser getOwner() {
        return mOwner;
    }

    public void setOwner(IUser newOwner) {
        mOwner = newOwner;
    }

    public boolean enterRoom(IUser user) {
        if(!isUserInRoom(user))
            mUsers.add(user);
        ((User)user).setRoomId(mId);
        return true;
    }

    public int exitRoom(IUser user) {
        if(!isUserInRoom(user)) {
            return AbstractGame.ERROR_USER_NOT_IN_ROOM;
        }

        for(IPlayGame game : mGames) {
            if(game.isInPlaying(user)) {
                return AbstractGame.ERROR_USER_PLAYING_EXIT;
            }
        }

        for(int i = 0; i < mUsers.size(); i++) {
            if(user.equals(mUsers.get(i))) {
                mUsers.remove(i);
                ((User)user).setRoomId(-1);
                return  AbstractGame.ERROR_NONE;
            }
        }
        return AbstractGame.ERROR_UNKNOWN;
    }

    public void removeUser(IUser user) {
        for(IPlayGame game : mGames) {
            if(game.isInPlaying(user)) {
                ((PlayGame)game).quitGame(user);
            }
        }

        for(int i = 0; i < mUsers.size(); i++) {
            if(user.equals(mUsers.get(i))) {
                mUsers.remove(i);
                ((User)user).setRoomId(-1);
                return;
            }
        }
    }

    @Override
    public boolean isUserInRoom(IUser user) {
        for(int i = 0; i < mUsers.size(); i++) {
            if(user.equals(mUsers.get(i)))
                return true;
        }
        return false;
    }

    public IPlayGame createGame(IUser creator, Object gameInfo) {
        PlayGame game = new PlayGame(this, "Desk" + mGames.size(), creator, gameInfo);
        mGames.add(game);
        return game;
    }

    public List<IPlayGame> getGames() {
        return mGames;
    }

    public List<IUser> getUsers() {
        return mUsers;
    }

    public String getPassword() {
        return mPassword;
    }

    public Room clone() {
        Room newRoom = new Room();
        newRoom.mId = mId;
        newRoom.mName = mName;
        newRoom.mOwner = mOwner;
        newRoom.mPassword = mPassword;
        newRoom.mGames = new ArrayList<>();
        newRoom.mUsers = new ArrayList<>();
        newRoom.mGames.addAll(mGames);
        newRoom.mUsers.addAll(mUsers);
        return newRoom;
    }

    @Override
    public boolean needPassword() {
        return mPassword != null && !mPassword.isEmpty();
    }

    @Override
    public boolean equals(Object other) {
        return other instanceof Room && mName.equals(((Room) other).mName);
    }

    @Override
    public String toString() {
        return "Room[name=" + mName + "]";
    }
}
